package org.example.controller;

import com.google.protobuf.Api;
import lombok.extern.slf4j.Slf4j;
import org.example.common.ApiResponse;
import org.example.common.MD5Utils;
import org.example.common.TokenStorage;
import org.example.entity.system.RoleOption;
import org.example.entity.system.User;
import org.example.service.UserService;
import org.example.service.impl.PermissionServiceImpl;
import org.example.service.impl.RoleServiceImpl;
import org.example.service.impl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.*;

/**
 * @Description
 * @Author 魏锴
 * @Date 2024/1/3
 */
@Slf4j
@Controller
@ResponseBody
@RequestMapping("/index")
@PropertySource(value = "classpath:avatar.properties", encoding = "utf-8")
public class IndexController {
    @Value("${upload_url}")
    private String UPLOAD_DIR;
    @Autowired
    private UserServiceImpl userService;
    @Autowired
    private PermissionServiceImpl permissionService;
    @Autowired
    private RoleServiceImpl roleService;

    @GetMapping("/hello")
    public String hello() {
        return "Hello World!";
    }

    @PostMapping("/login")
    public ApiResponse Login(HttpSession session, String username, String password) {
//        long time = new Date().getTime();
        System.out.println("<------ 用户登录开始 ------>");
        System.out.println("username: " + username + ",  password: " + password);
        User user = userService.getUser(username);
        if (user == null) return ApiResponse.failure("该用户不存在" + username);
        if (!Objects.equals(user.getPassword(), password)) return ApiResponse.failure("密码错误");
        String token = MD5Utils.MD5Lower(username + password, new Date().toString());//加盐加密
        List<Integer> roles = roleService.getRolesByUser(user.getId());
        if (roles.contains(1)) {//管理员额外添加身份
            List<Integer> rolesList = roleService.getRoleIdList();
            rolesList.remove((Integer) 1);
            roles.addAll(0, rolesList);//将管理员页面放在最后
        }
        List<Integer> perms = permissionService.getPermsByRoles(roles);
        session.setAttribute(token + ":roles", roles);
        session.setAttribute(token + ":perms", perms);
        session.setAttribute(token, user.getId());
//        System.out.println("token:       " + token);
//        System.out.println("token-roles: " + roles);
//        System.out.println("token-perms: " + perms);
//        System.out.println("花费时间: " + (new Date().getTime() - time));
        System.out.println("<------ 用户登录结束 ------>");
        HashMap<String,Object> data=new HashMap<>();
        data.put("token",token);
        data.put("username",user.getUsername());//返回user类
        data.put("avatar",user.getAvatar());//返回user类
        return ApiResponse.ok("用户验证成功", data);
    }

    @GetMapping("/getBorder")
    public ApiResponse getBorder(HttpSession session) {
        //根据username获得边框栏菜单信息
        String token = TokenStorage.getToken();//获取token
        Object obj = session.getAttribute(token + ":roles");
        if (obj == null) return ApiResponse.certificationExpires();
        List<Integer> roles = (List<Integer>) obj;
        List<RoleOption> roleOptions = new ArrayList<>();
        for (int role_id : roles) {
            roleOptions.add(
                    new RoleOption(
                            roleService.getRoleById(role_id),
                            permissionService.getPermOpsByRoleId(role_id)));
        }
        return ApiResponse.ok("边框栏信息已更新", roleOptions);//返回选项列表
    }
    @PostMapping("/userInfo")
    public ApiResponse updateUserInfo(HttpSession session,String username,String avatar){//对用户名和头像信息进行修改
        try{if (userService.updateUserInfo((Integer) session.getAttribute(TokenStorage.getToken()),username,avatar))
                return ApiResponse.ok("用户信息修改成功");
        } catch (Exception e){e.printStackTrace();}
        return ApiResponse.failure("用户信息修改失败");
    }
    @PostMapping("/updatePassword")
    public ApiResponse updatePassword(HttpSession session,String oldPassword,String newPassword){
        int id = (int) session.getAttribute(TokenStorage.getToken());//获得user_id
        System.out.println(id);
        String password = userService.getPasswordByUser(id);
        System.out.println("old = "+oldPassword+", new = "+newPassword+", password = "+password);
        if (password.equals(oldPassword) && !"".equals(newPassword) && userService.updatePassword(newPassword,id))
            return ApiResponse.ok("密码修改成功");
        return ApiResponse.failure("密码修改失败");
    }
    @PostMapping("/upload/avatar")
    public ApiResponse uploadAvatar(HttpSession session, @RequestParam("file")MultipartFile file){
        try{
            System.out.println(UPLOAD_DIR);
            int user_id=(int) session.getAttribute(TokenStorage.getToken());//从session中获取username
            File dir = new File(UPLOAD_DIR);
            if (!dir.exists()) dir.mkdirs();
            String file_name = MD5Utils.MD5Lower(String.valueOf(user_id), new Date().toString())+".jpg";
            String finalSavePath = UPLOAD_DIR + file_name;
            System.out.println(new File(finalSavePath));
            // 保存文件
            InputStream inputStream = file.getInputStream();
            Files.copy(inputStream, Paths.get(finalSavePath), StandardCopyOption.REPLACE_EXISTING);

            File oldAvatar= new File(UPLOAD_DIR + userService.getAvatar(user_id));
            oldAvatar.delete();//删除旧文件
            userService.saveAvatar(user_id,file_name);//记录新文件
            return ApiResponse.ok("上传成功",file_name);
        }catch (Exception e){
            e.printStackTrace();
            return ApiResponse.failure("上传失败");
        }
    }
}
